/**
 * 安卓白金英雄坛制作组 <br>
 * 文件名：AttackStatus.java <br>
 * 创建时间：2013-8-7 下午8:22:58 <br>
 * 所属项目：GmudEX <br>
 * @author 12548 <br>
 */
package lostland.gmud.exv2.battle.proc;

import com.orhanobut.logger.Logger;

import lostland.gmud.exv2.Game;
import lostland.gmud.exv2.GameConstants;
import lostland.gmud.exv2.Gmud;
import lostland.gmud.exv2.battle.BattleScreen;
import lostland.gmud.exv2.battle.StuntData;
import lostland.gmud.exv2.battle.ViewScreen;
import lostland.gmud.exv2.data.Gesture;
import lostland.gmud.exv2.data.Item;
import lostland.gmud.exv2.data.Npc;
import lostland.gmud.exv2.data.Room;
import lostland.gmud.exv2.data.Skill;

/**
 * 类名：AttackStatus <br>
 * 说明：战斗中的攻击状态
 *
 * @author 12548
 */
public class AttackStatus extends Status {

	public Gesture ag;
	public Skill as;

	public float hitBouns = 0f;
	public float dmgBouns = 0f;
	public Item anqi = null;

	boolean isAnti = false;

	/**
	 *
	 */
	public AttackStatus(Npc zdp, Npc bdp, boolean isAnti) {
		super(zdp, bdp);
		this.isAnti = isAnti;
	}

	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.battle.proc.Status#execute()
	 */
	@Override
	public void execute() {
		int hit = 0;
		String prefix = "";

		if (evd()) {
			Gesture ges = bdp.getEquipedSkill(2).chooseAGesture();

			new ViewScreen(BattleScreen.bsp(zdp, bdp, ges.c)).pushToGame();

//			if(bdp.using(GmudGame.getInstance().xdata.get("SKILLID_青翼绝尘"))){
//				if(ges.dmg_type == 4){
//					//吸血杀手
//					zdp.sp -= bdp.skills[48];
//					zdp.hp -= bdp.skills[48];
//				}
//				else if(ges.dmg_type == 1){
//					//大空翼
//					zdp.sp -= (int)(bdp.skills[48] * 0.66);
//					zdp.sp -= bdp.skills[48] / 2;
//				}
//				else if(ges.dmg_type == 2){
//					//飞沙走石
//					if(bdp.skills[48] > Math.random() * 250)
//						zdp.setTransfixed(zdp.getDz()+1);
//				}
//			}

			if (bdp.haveTalent(58)) // 天赋效果58
			{
				bdp.setFp((int) (bdp.getFp() + bdp.maxfp * 0.2));
				if (bdp.getFp() > bdp.maxfp) {
					bdp.setFp(bdp.maxfp);
				}
			}

			if (zdp.haveTalent(47) && Gmud.rand.nextBoolean()) // 天赋效果47
			{
				new PreAttackStatus(zdp, bdp, null, "【我武维扬】").pushToBattle();
			}

		} else if (blk()) {
			Gesture ges = Gmud.skill[Skill.KIND_ZHAOJIA].chooseAGesture(zdp, bdp);
			new ViewScreen(BattleScreen.bsp(zdp, bdp, ges.c)).pushToGame();
			if (antiAttack()) {
				new PreAttackStatus(bdp, zdp, null, "【格挡反击】", false, false, true).pushToBattle();
			}
		} else if (bdp.getBuff(4) > 0 && Gmud.rand.nextBoolean()) {
			new ViewScreen(BattleScreen.bsp(zdp, bdp, "$N没料到这一击却打空，原来打中的只是个影子")).pushToGame();
		} else {
			int a;
			if (anqi != null) {
				a = (int) ((zdp.getAttr(Room.ATTR_STR) + zdp.getAttr(Room.ATTR_ADS) / 2 + anqi.getA3() + Math.min(zdp.getFp() / 20.0, 150)) *
						((ag.force1 + ag.force2) / 100.0 + 0.8));
			} else if (zdp.getFp() > 0 && zdp.getAttr(Room.ATTR_ADS) > 0) {
				a = (int) ((zdp.getAttr(Room.ATTR_STR) + zdp.getAttr(Room.ATTR_ADS) / 2 +
						zdp.getAttr(Room.ATTR_ATK) + Math.min(zdp.getFp() / 20.0, 150)) *
						(ag.force1 / 100.0) + (zdp.getAttr(Room.ATTR_STR) +
						zdp.getAttr(Room.ATTR_ADS) + zdp.getAttr(Room.ATTR_ATK) +
						Math.min(zdp.getFp() / 20.0, 150)) *
						(ag.force2 / 100.0 + 0.8));
				zdp.setFp(zdp.getFp() - zdp.getAttr(Room.ATTR_ADS));
				if (zdp.getFp() < 0) {
					zdp.setFp(0);
				}
			} else {
				a = (int) ((zdp.getAttr(Room.ATTR_STR) + zdp.getAttr(Room.ATTR_ATK)) * ((ag.force1 + ag.force2) / 100.0 + 0.8));
			}

			a = Math.max(a, 0);

			if(zdp.haveTalent(1007) && zdp.getSp() <= (zdp.getAttr(Room.ATTR_MAXHP) * 0.3)) // 天赋效果1007
			{
				prefix += "【天魔】";
				a *= 3;
			}

			if (zdp.haveTalent(1012) && (bdp.haveFlag(Npc.FLAG_BADMAN) || bdp.haveFlag(Npc.FLAG_NICEGUY))) // 天赋效果1012
			{
				prefix += "【追魂】";
				a *= 1.3f;
			}

			if (zdp.haveTalent(110)) // 天赋效果110
			{
				if (Math.random() < 0.3) {
					bdp.setTransfixed(bdp.getDz() + 1);
					if (Math.random() < 0.2) {
						bdp.setTransfixed(bdp.getDz() + 2);
					}
					prefix += "【威德自在】";
				}
			}

			int rune = zdp.getRuneValue(1, 0);
			if (rune > 0) {
				bdp.setAtk_bouns(bdp.getAtk_bouns() - rune);
				prefix += zdp.getRunePrefix(1, 0);
			}
			rune = zdp.getRuneValue(1, 1);
			if (rune > 0) {
				bdp.setDef_bouns(bdp.getDef_bouns() - rune);
				prefix += zdp.getRunePrefix(1, 1);
			}
			rune = zdp.getRuneValue(1, 2);
			if (rune > 0) {
				bdp.setHit_bouns(bdp.getHit_bouns() - rune);
				prefix += zdp.getRunePrefix(1, 2);
			}
			rune = zdp.getRuneValue(1, 3);
			if (rune > 0) {
				bdp.setEvd_bouns(bdp.getEvd_bouns() - rune);
				prefix += zdp.getRunePrefix(1, 3);
			}
			rune = zdp.getRuneValue(1, 4);
			if (rune > 0 && bdp.getDz() == 0 && Math.random() < (float) rune / 100) {
				bdp.setTransfixed(2);
				prefix += zdp.getRunePrefix(1, 4);
			}
			rune = zdp.getRuneValue(1, 5);
			if (rune > 0) {
				if (Math.random() < (float) rune / 100) {
					bdp.setStunt(false);
					prefix += zdp.getRunePrefix(1, 5);
				} else {
					bdp.setStunt(true);
				}
			}


			int dmg = (int) (a / 2.0 + Math.random() * a / 2.0);

			dmg *= 1f + dmgBouns;

			if (zdp.haveTalent(2074)) {
				dmg *= 0.5;
			}

			if (bdp.haveTalent(2072)) {
				dmg *= 2;
			}

			if (zdp.haveTalent(2075) || bdp.sex == 1) {
				dmg *= 0.5;
			}

			if (zdp.haveTalent(2073)) {
				bdp.addGauge(-2);
			}


			Logger.i("" + dmg);
			Logger.i("" + a);

			if (critAttack()) {
				prefix += "【暴击】";
				dmg = (int) (a * critTimes());


				if (zdp.haveTalent(1002)) // 天赋效果1002
				{
					dmg *= 1.2f;
					prefix += "【禁断之力】";
				}

				if (zdp.haveTalent(1009)) // 天赋效果1009
				{
					prefix += "【怒意狂击】";
					bdp.setTransfixed(bdp.getDz() + 2);
				}


				if (zdp.haveTalent(94)) // 天赋效果94
				{
					new PreAttackStatus(zdp, bdp, null, "【仁王符灵】").pushToBattle();
					if (Gmud.rand.nextBoolean()) {
						new PreAttackStatus(zdp, bdp, null, "【仁王符灵】").pushToBattle();
					}
				}


//				if(bdp.using(GmudGame.getInstance().xdata.get("SKILLID_凌波微步")))
//				{
//					prefix += "【凌波】";
//					dmg *= 0.5;
//					GmudGame.logInfo("PreAttackStatus", "凌波微步：暴击伤害减少");
//				}

				if (bdp.haveTalent(30)) {
					// 天赋效果 开卷有益
					prefix += "【开卷有益】";
					bdp.flag(32768);
				}

				Logger.i("" + dmg);
			}


			int armor = bdp.getAttr(Room.ATTR_BON) / 2 + bdp.getAttr(Room.ATTR_DEF) / 4 - 10;

			final double armor_rate = 0.04;

			Logger.d("护甲：" + armor);


			if (armor >= 0) {
				dmg *= 1.0 - armor * armor_rate / (1 + armor * armor_rate);
			} else {
				dmg /= Math.pow(0.94, -armor);
			}

			if (dmg <= 0) {
				dmg = (int) (Math.random() * 4 + 1);
			}

			Logger.i("" + dmg);

			bdp.dmg(dmg, ag.dmgfix, zdp);

			if (bdp.haveTalent(126) && Gmud.rand.nextBoolean()) // 天赋效果126
			{
				zdp.dmg(dmg, ag.dmgfix, zdp);
				prefix += "【道德归元】";
			}

			rune = zdp.getRuneValue(1, 6);
			if(rune > 0 && Math.random() < (float) rune / 100 && !bdp.isImmuHpDmg()) {
				prefix += zdp.getRunePrefix(1, 6);
				if(bdp.getHp() > bdp.getSp()) {
					bdp.setHp(bdp.getSp());
				}
			}

			if(bdp.haveTalent(2076)) {
				zdp.addGauge(-zdp.getGauge());
			}

			prefix += bdp.getBattleData().hurtpf;
			bdp.getBattleData().hurtpf = "";

			zdp.setSp(zdp.getSp() + zdp.skills[41] * dmg / 100);
			if(zdp.getSp() > zdp.getHp()) {
				zdp.setSp(zdp.getHp());
			}


			hit = 2;

			if (bdp == BattleScreen.getInstance().p2()) {
				hit = 1;
			}

			if (bdp.getGauge() < GameConstants.GAUGE_MAX) {
				bdp.addGauge(1);
			} else {
				//TODO: 暴气
				int t = Gmud.rand.nextInt(100);
				if (t < 60) {

//					PreAttackStatus pas = new PreAttackStatus(bdp, zdp, null, "【怒气爆发·" + bdp.getAttackSkill().name + "】");
//					pas.hitBouns = -0.05f;
//					pas.dmgBouns = 0.2f;
//					Gmud.bs.push(pas);

					int avStunts[] = new int[0];
					for (int i = 0; i < StuntData.getInstance().size(); i++) {
						if (StuntScreen.canuse(bdp, i)) {
							avStunts = Gmud.push_back(avStunts, i);
							Logger.i(StuntData.getInstance(i).name + " is avalible");
						}
					}

					Logger.i(avStunts.length + " Stunts avalible in total");

					if (avStunts.length > 0 && bdp.isStuntAvaliable()) {
						// NPC发动绝招
						bdp.addGauge(-GameConstants.GAUGE_MAX);
						StuntScreen.process(bdp, zdp, avStunts[(int) (Math.random() * avStunts.length)]);
						new ViewScreen(BattleScreen.bsp(AttackStatus.this.bdp, AttackStatus.this.zdp,
								"【怒气爆发】$N凭藉一腔怒意发动绝招！")).pushToGame();
						// GmudGame.getInstance().pushScreen(new ViewScreen(GmudGame.getInstance()));
						// Gmud.bs.push(new DummyStatus());
					}

				} else if (t < 80 && bdp.skillsckd[3] > 0) {
					new Status(zdp, bdp) {

						@Override
						public void execute() {
							AttackStatus.this.bdp.addGauge(-GameConstants.GAUGE_MAX);
							AttackStatus.this.bdp.rec((int) (AttackStatus.this.bdp.getAttr(Room.ATTR_MAXHP) * 0.1f + AttackStatus.this.bdp.skills[AttackStatus.this.bdp.skillsckd[3]] / 2.0));
							AttackStatus.this.bdp.setFp(AttackStatus.this.bdp.getFp() + (int) (AttackStatus.this.bdp.maxfp * 0.1f + AttackStatus.this.bdp.skills[AttackStatus.this.bdp.skillsckd[3]] / 2.0));
							AttackStatus.this.bdp.setDz(0);
//							Gmud.bs.push(new DummyStatus());
							new ViewScreen(BattleScreen.bsp(AttackStatus.this.bdp, AttackStatus.this.zdp,
									"【怒气爆发】$N凭藉一腔怒意运转内功，冲开穴道并回复了部分状态！", anqi)).pushToGame();
						}
					}.pushToBattle();
				}
			}


			new ViewScreen(
					Game.getInstance(), hit, BattleScreen.bsp(zdp, bdp, prefix + get_damage_string(ag.dmg_type, dmg)) + shfj(bdp)).pushToGame();
		}


//		Gmud.bs.push(new DummyStatus(hit));
	}


	private String get_damage_string(int damage_type, int dmg) {
		String s[];
		s = new String[9];
		s[0] = "结果没有造成伤害";

		switch (damage_type) {
			case 2:
				s[1] = "只轻轻地刺破$n皮肉";
				s[2] = "在$n身上刺出一个创口";
				s[3] = "结果$n被刺入了寸许";
				s[4] = "结果刺得$n退了几步";
				s[5] = "结果刺出一个血肉模糊的伤口";
				s[6] = "结果$n被刺中要害，痛苦地倒了下来";
				s[7] = "结果$n被穿胸而过，大声咳嗽起来";
				s[8] = "结果$n被刺了个透明窟窿，鲜血飞溅";
				break;
			case 3:
				s[1] = "只是轻轻地碰到$n";
				s[2] = "在$n的伤处造成一处瘀青";
				s[3] = "结果一击命中，$n被打肿了一块老高";
				s[4] = "结果一击命中，$n痛苦地闷哼了一声";
				s[5] = "结果『砰』的一声，$n退了两步";
				s[6] = "结果$n连退了好几步，差一点摔倒";
				s[7] = "结果重重的击中，$n吐出一口鲜血";
				s[8] = "结果一声巨响，$n像捆稻草般飞了出去";
				break;
			case 5:
				s[1] = "只是抓破$n的一点皮";
				s[2] = "结果$n被抓出了五条淡淡的血痕";
				s[3] = "结果一爪命中，$n被抓出了五条血沟";
				s[4] = "结果抓下了$n一小块皮肉";
				s[5] = "结果$n皮开肉破，鲜血流了下来";
				s[6] = "结果$n被抓出了五个血洞，鲜血急喷";
				s[7] = "结果$n被连皮带肉抓下了一大块，露出了骨头";
				s[8] = "结果『喀嚓』一声，$n的骨头被抓得粉碎";
				break;
			case 1:
				s[1] = "只轻轻地划破$n的皮肉";
				s[2] = "划出一道细长的血痕";
				s[3] = "结果$n被割出了一道伤口";
				s[4] = "结果$n被划出了一道血淋淋的伤口";
				s[5] = "结果$n被划出了一道又长又深的伤口";
				s[6] = "结果$n被削下了一大块肉，看来晚上有肉吃了";
				s[7] = "结果$n被砍出了一道深及见骨的可怕伤口";
				s[8] = "结果$n的骨头应声砍断，看来下辈子只能坐轮椅了";
				break;
			case 4:
				s[1] = "$n退了半步，毫发无损";
				s[2] = "给$n造成一处瘀伤";
				s[3] = "结果一击命中，$n痛得弯下腰";
				s[4] = "结果$n痛苦地闷哼了一声，显然受了点内伤";
				s[5] = "结果$n摇摇晃晃，一跤摔倒在地";
				s[6] = "结果$n脸色一下变得惨白，连退了好几步";
				s[7] = "结果『轰』的一声，$n口中鲜血狂喷而出";
				s[8] = "结果$n一声惨叫，像滩软泥般塌了下去";
				break;
			case 0:
			default:
				s[1] = "结果对$n造成的伤害微不足道";
				s[2] = "结果对$n造成了轻微的伤害";
				s[3] = "结果对$n造成了一处伤害";
				s[4] = "结果对$n造成了颇为严重的伤害";
				s[5] = "结果对$n造成了相当严重的伤害";
				s[6] = "结果对$n造成了十分严重的伤害";
				s[7] = "结果对$n造成了极其严重的伤害";
				s[8] = "结果对$n造成了非常可怕的严重伤害";
		}

		if (dmg <= 0)
			return s[0];
		else if (dmg < 10)
			return s[1];
		else if (dmg < 20)
			return s[2];
		else if (dmg < 40)
			return s[3];
		else if (dmg < 80)
			return s[4];
		else if (dmg < 120)
			return s[5];
		else if (dmg < 160)
			return s[6];
		else if (dmg < 200)
			return s[7];
		else
			return s[8];
	}

	private String shfj(Npc p) {
		String t;
		String s1[] = new String[]{
				"看起来充满活力，一点也不累",
				"似乎有些疲惫，但是十分有活力",
				"看起来可能有些累了",
				"动作似乎开始有点不太灵光",
				"气喘嘘嘘，看起来状况并不太好",
				"十分疲惫，看来需要好好休息了",
				"已经头重脚轻，正在勉力支撑",
				"看起来已经力不从心了",
				"摇头晃脑，眼看就要倒在地上",
				"已经陷入半昏迷状态"
		};
		String s2[] = new String[]{
				"看起来气血充盈，并没有受伤",
				"似乎受了点轻伤，不过看不出来",
				"看起来可能受了点轻伤",
				"受了几处伤，不过似乎并不碍事",
				"受伤不轻，看起来状况并不太好",
				"动作开始散乱，看来受的伤不轻",
				"已经伤痕累累，正在勉力支撑",
				"受伤相当重，只怕有生命危险",
				"伤重之下已经难以支撑",
				"受伤过重，已经命在旦夕了",
				"受伤过重，随时都可能断气"
		};
		int t1 = p.getAttr(Room.ATTR_MAXHP) - p.getSp();
		int t2 = p.getAttr(Room.ATTR_MAXHP) - p.getHp();

		if (t2 >= p.getAttr(Room.ATTR_MAXHP)) {
			t = s2[s2.length - 1];
		} else if (t1 >= t2) {
			if (t1 >= p.getAttr(Room.ATTR_MAXHP)) {
				t = s1[s1.length - 1];
			} else {
				t = s1[(int) (1.0 * t1 * s1.length / p.getAttr(Room.ATTR_MAXHP))];
			}
		} else {
			t = s2[(int) (1.0 * t2 * s2.length / p.getAttr(Room.ATTR_MAXHP))];
		}
		return BattleScreen.bsp(zdp, bdp, "（$n" + t + "）");

	}


	boolean evd() {

		if (zdp.haveTalent(2048)) // 天赋效果 明断天启
			return false;
		else if (bdp.haveTalent(2052)) // 天赋效果 金色闪光
			return true;

		Logger.w("正在获取命中率");
		double h = zdp.getBattleHit(as);

		double hr = h / (bdp.getBattleEvd() + h);

		if (anqi != null) {
			hr *= (anqi.getA4() - 10.0) * 0.01 + 1;
		}

		hr += hr * (1 - hr);

//		if(zdp.using(GmudGame.getInstance().xdata.get("SKILLID_游龙身法")))
//		{
//			hr *= 1.15;
//			GmudGame.logInfo("PreAttackStatus", "游龙身法：命中率增加");
//		}
//
//		if(bdp.using(GmudGame.getInstance().xdata.get("SKILLID_无影遁形")))
//		{
//			hr *= 0.85;
//			GmudGame.logInfo("PreAttackStatus", "无影遁形：命中率减少");
//		}
//
		if (zdp.haveTalent(29) && !zdp.equips(Gmud.findItem("老花镜").getId())) // 天赋效果 老眼昏花
		{
			hr *= 0.5;
		}

		hr *= 1f + hitBouns;

		Logger.i("命中率=" + hr);
		boolean isHit = Math.random() <= hr;
		Logger.i("命中=" + isHit);

		return !isHit;
	}

	boolean blk() {
		if (anqi != null)
			return false; //暗器不能被格挡
		if (zdp.haveTalent(2048)) // 天赋效果 明断天启
			return false;

		double b = bdp.getBattleBLK();

		double hr = b / (zdp.getBattleHit(as) + b);

		hr *= 0.3;


		Logger.i("格挡率：" + hr);

		boolean isBlocked = Math.random() <= hr;
		Logger.i("格挡：" + isBlocked);
		return isBlocked;
	}

	boolean critAttack() {

		if (zdp.haveTalent(1004) && isAnti) // 天赋效果1004
			return true;

		double rr = 0.05 * Game.getInstance().data.game_difficulty + 0.05;

//		if(zdp.using(GmudGame.getInstance().xdata.get("SKILLID_鹤翔身法")))
//		{
//			rr *= 1.1;
//			GmudGame.logInfo("PreAttackStatus", "鹤翔身法：暴击率增加");
//		}
//
//		if(bdp.using(GmudGame.getInstance().xdata.get("SKILLID_万流归一")))
//		{
//			rr *= 0.8;
//			GmudGame.logInfo("PreAttackStatus", "万流归一：暴击率减少");
//		}

		boolean da = Math.random() < rr;
		Logger.i("暴击：" + da);
		return da;
	}

	boolean antiAttack() {
		if (isAnti) return false; // 反击不触发反击

		if(bdp.haveTalent(1010) && (bdp.getSp() <= bdp.getAttr(Room.ATTR_MAXHP) * 0.5)) // 天赋效果1010
			return true;

		double r = 0.1 + 0.1 * Game.getInstance().data.game_difficulty;


		return Math.random() < r;
	}


	float critTimes() {

		float t = 1f;

		t += zdp.getAttr(Room.ATTR_WXG) * 0.005 * Game.getInstance().data.game_difficulty;

		Logger.i("暴击倍数：" + t);

		return t;
	}

}
